function LaserEmitter(x, y, angle) {
  this.x = x;
  this.y = y;
  this.angle = angle;
  this.brightness = 100;
  this.targetR = 0;
  this.targetG = 0;
  this.targetB = 0;
  this.nozzleWidth = 10.0;
  this.nozzleHeight = 10.0;
  this.mainWidth = 40.0;
  this.mainHeight = 20.0;
  this.targetWidth = 4.0;
  this.targetHeight = 15.0;

  // debug
  this.collisionMarkers = new Array();
  this.cornerMarkers = new Array();

  LaserEmitter.prototype.emitsLaser = function() {
    return true;
  }

  LaserEmitter.prototype.getLaser = function() {
    return new LaserPath(this.x, this.y, this.angle);
  }

  LaserEmitter.prototype.update = function(objects) {
    // TODO(erocke): check if laser has beam coming into it that changes its state maybe?
    ;
  }

  LaserEmitter.prototype.render = function(processing) {
    processing.pushMatrix();
    processing.fill(this.brightness, this.brightness, this.brightness);
    processing.translate(this.x, this.y);
    processing.rotate(processing.radians(this.angle));
    processing.quad(0, -this.nozzleHeight/2,
		    0, this.nozzleHeight/2,
		    -this.nozzleWidth, this.nozzleHeight/2,
		    -this.nozzleWidth, -this.nozzleHeight/2);
    processing.quad(-this.nozzleWidth, -this.mainHeight/2,
		    -this.nozzleWidth, this.mainHeight/2,
		    -this.nozzleWidth - this.mainWidth, this.mainHeight/2,
		    -this.nozzleWidth - this.mainWidth, -this.mainHeight/2);
    processing.fill(this.targetR, this.targetG, this.targetB);
    processing.quad(-this.nozzleWidth - this.mainWidth + this.targetWidth, -this.targetHeight / 2,
		    -this.nozzleWidth - this.mainWidth + this.targetWidth, this.targetHeight / 2,
		    -this.nozzleWidth - this.mainWidth, this.targetHeight / 2,
		    -this.nozzleWidth - this.mainWidth, -this.targetHeight / 2);
    processing.popMatrix();

    if (this.collisionMarkers.length > 0) {
      for (var i = 0; i < this.collisionMarkers.length; ++i) {
	processing.fill(200, 40, 90);
	//processing.ellipse(this.collisionMarkers[i].x, this.collisionMarkers[i].y, 10, 10);
      }
    }
    if (this.cornerMarkers.length > 0) {
      for (var i = 0; i < this.cornerMarkers.length; ++i) {
	processing.fill(90, 40, 200);
	//processing.ellipse(this.cornerMarkers[i].x, this.cornerMarkers[i].y, 10, 10);
      }
    }
  }
    
  LaserEmitter.prototype.collides = function() {
    return false;
  }

  LaserEmitter.prototype.sign = function(x) {
    if (x < 0)
      return -1;
    return 1;
  }

  LaserEmitter.prototype.calculateSideInterruptDistance = function(x1, y1, x2, y2, x3, y3, x4, y4) {
      var collisionXNumerator = (x1 * y2 - y1 * x2) * (x3 - x4) - (x1 - x2) * (x3 * y4 - y3 * x4);
      var collisionXDenominator = (x1 - x2) * (y3 - y4) - (y1 - y2) * (x3 - x4);
      if (collisionXDenominator == 0) {
	return -1;
      }
      var collisionYNumerator = (x1 * y2 - y1 * x2) * (y3 - y4) - (y1 - y2) * (x3 * y4 - y3 * x4);
      var collisionYDenominator = collisionXDenominator;

      var collisionX = collisionXNumerator / collisionXDenominator;
      var collisionY = collisionYNumerator / collisionYDenominator;
      var dist = Math.sqrt((collisionX - x1) * (collisionX - x1) + (collisionY - y1) * (collisionY - y1));

      var collisionMarker = new Object();
      collisionMarker.x = collisionX;
      collisionMarker.y = collisionY;
      this.collisionMarkers.push(collisionMarker);

      // Check if collision is inside the length of the edge
      var lineCenterX = (x3 + x4) / 2.0;
      var lineCenterY = (y3 + y4) / 2.0;
      var lineLength = Math.sqrt((x4 - x3) * (x4 - x3) + (y4 - y3) * (y4 - y3));
      var distanceToLineCenter = Math.sqrt((collisionX - lineCenterX) * (collisionX - lineCenterX)
					   + (collisionY - lineCenterY) * (collisionY - lineCenterY));
      if (distanceToLineCenter > lineLength / 2.0) {
	return -1;
      }

      // Check if collision is in the right laser direction
      if (this.sign(collisionX - x1) != this.sign(x2 - x1)) {
	return -1;
      }
      if (this.sign(collisionY - y1) != this.sign(y2 - y1)) {
	return -1;
      }
      
      return dist;
  }

  LaserEmitter.prototype.getInterruptDistance = function(vectorX, vectorY, vectorAngle) {
    // interrupts the laser if the laser hits the body.
    // check each of the 4 lines around it for collisions
    this.collisionMarkers.length = 0;
    this.cornerMarkers.length = 0;
    var cos = Math.cos(Math.PI * vectorAngle / 180.0);
    var sin = Math.sin(Math.PI * vectorAngle / 180.0);
    var xBaseline = new Array(-this.nozzleWidth, -this.nozzleWidth,
			      -this.nozzleWidth - this.mainWidth, -this.nozzleWidth - this.mainWidth);
    var yBaseline = new Array(-this.mainHeight / 2, this.mainHeight / 2, this.mainHeight / 2, -this.mainHeight / 2);
    var cosines = new Array(+cos, -cos, -cos, +cos);
    var sines = new Array(-sin, -sin, +sin, +sin);
    var cornerx = new Array();
    var cornery = new Array();
    for (var corner = 0; corner < 4; corner++) {
      var origAngle = 180 * Math.atan(yBaseline[corner] / xBaseline[corner]) / Math.PI;
      var distance = Math.sqrt(xBaseline[corner] * xBaseline[corner] + yBaseline[corner] * yBaseline[corner]);
      var newAngle = origAngle + this.angle + 180;
      cornerx[corner] = this.x + Math.cos(Math.PI * newAngle / 180.0) * distance;
      cornery[corner] = this.y + Math.sin(Math.PI * newAngle / 180.0) * distance;
      var cornerMarker = new Object();
      cornerMarker.x = cornerx[corner];
      cornerMarker.y = cornery[corner];
      this.cornerMarkers.push(cornerMarker);
    }
    var closest = -1;
    for (var side = 0; side < 4; side++) {
      var x1 = vectorX;
      var x2 = vectorX + cos;
      var y1 = vectorY;
      var y2 = vectorY + sin;
      var x3 = cornerx[side];
      var y3 = cornery[side];
      var x4 = cornerx[(side+1) % 4];
      var y4 = cornery[(side+1) % 4];
      var sideDistance = this.calculateSideInterruptDistance(x1, y1, x2, y2, x3, y3, x4, y4);
      if (closest < 0 || closest > sideDistance) {
	closest = sideDistance;
      }
    }
    return closest;
  }

  LaserEmitter.prototype.handleLaser = function(x, y, angle) {
  }
}

ActivatableLaserEmitter.prototype = new LaserEmitter;
function ActivatableLaserEmitter(x, y, angle) {
  LaserEmitter.apply(this, new Array(x, y, angle));
  this.isActive = false;
  this.brightness = 200;
  this.path = new LaserPath(this.x, this.y, this.angle);
  this.path.isActive = this.isActive;

  ActivatableLaserEmitter.prototype.getLaser = function() {
    return this.path;
  }

  ActivatableLaserEmitter.prototype.deactivate = function() {
    this.path.isActive = false;
    this.isActive = false;
  }

  ActivatableLaserEmitter.prototype.activate = function() {
    this.path.isActive = true;
    this.isActive = true;
  }

  ActivatableLaserEmitter.prototype.update = function() {
    //this.deactivate();
  }

  //target by coming in through the back end.
  ActivatableLaserEmitter.prototype.handleLaser = function(x, y, angle) {
    this.activate();
    //this.path.update();
  }
}
